﻿#define Download
using System;
using System.Globalization;
using System.Threading;
using Halk.Analyser;
using Halk.Config;

namespace Halk.Spider
{
    public class NovelSpider : SpiderBase
    {
        //private class AnalyserAll
        //{
        //    //public int DiffCount { get; set; }
        //    public AnalyseArticle AnalyseArticler { get; set; }
        //    public AnalyseBookReader AnalyseBookReaderer { get; set; }
        //    public AnalyseChapter AnalyseChapter { get; set; }
        //}

        //private readonly Dictionary<string, AnalyserAll> _dicAnalyser = new Dictionary<string, AnalyserAll>();

        private void Initialize()
        {
            ConfigManage.Instace().Load();
            ContentManage.Instace().Load();

            //var rulePath = string.Format("conf/rule/{0}.xml", ConfigManage.Instace().GetConfig().RuleFlag);
            //FirstRule = RuleManage.Instace().GetRuleFormXml(rulePath);
        }

        public void Work()
        {
            Initialize();
            while (SystemManage.Instace().GetOnOff())
            {
                ConfigManage.Instace().MoveFirst();
                for (int i = 0; i < ConfigManage.Instace().GetSize(); i++)
                {
                    if (!ConfigManage.Instace().GetConfig().IsActive.Equals(1))
                    {
                        ConfigManage.Instace().MoveNext(); 
                        continue;
                    }

                    var rulePath = string.Format("conf/rule/{0}.xml", ConfigManage.Instace().GetConfig().RuleFlag);
                    FirstRule = RuleManage.Instace().GetRuleFormXml(rulePath);

                    AppCache.Instace().RepeatTimes = 0;
                    FirstAnalyseArticleList.Rule = FirstRule;
                    FirstAnalyseArticle.Rule = FirstRule;
                    FirstAnalyseBookReader.Rule = FirstRule;
                    FirstAnalyseChapter.Rule = FirstRule;

                    //test
                    //string content = Utils.HttpHelper.Get("http://www.kenwen.com/cview/35/35320/5414837.html",Encoding.GetEncoding("gbk"));
                    GetNovelList(ref _firstAnalyseArticleList,
                                 ref _firstAnalyseArticle,
                                 ref _firstAnalyseBookReader,
                                 ref _firstAnalyseChapter);
                    ConfigManage.Instace().MoveNext();
                    Thread.Sleep(ConfigManage.Instace().GetConfig().SleepTimes);
                }
            }
        }

        private void GetNovelList(ref AnalyseArticlelist analyseArticleList,
                                  ref AnalyseArticle analyseArticle,
                                  ref AnalyseBookReader analyseBookReader,
                                  ref AnalyseChapter analyseChapter)
        {
            var listUrl = analyseArticleList.GetNovelListUrl();
            for (var iPage = 1; iPage <= ConfigManage.Instace().GetConfig().MaxPage; ++iPage)
            {
                listUrl = listUrl.Replace("(*)", iPage.ToString(CultureInfo.InvariantCulture));
                analyseArticleList.SetContent(Utils.HttpHelper.Get(listUrl, analyseArticleList.Encode));
                analyseArticleList.AnalyseUrlList();
                foreach (string url in analyseArticleList.ArticleList)
                {
                    if (AppCache.Instace().RepeatTimes> ConfigManage.Instace().GetConfig().RepeatMax)
                        return;

                    try
                    {
                        //GetNovel("http://www.qidian.com/Book/2131628.aspx", ref analyseArticle);
                        //GetNovel("http://www.kkkxs.com/files/article/info/24/24182.htm", ref analyseArticle);
                        //GetNovel("http://www.hweisk.com/Book/13265/Index.aspx", ref analyseArticle);
                        GetNovel(url, ref analyseArticle);
                        analyseBookReader.Article = analyseArticle.Article;
                        if (string.IsNullOrEmpty(analyseArticle.Article.contentslink))
                        {
                            throw new Exception(string.Format("[102][NovelSpider]article contentslink is empty.{0}", url));
                        }
                        GetBookReaders(ref analyseArticle, ref analyseBookReader);
                        NovelStore.Instace().StoreNovel(ref analyseArticle);
                        analyseBookReader.Article = analyseArticle.Article;
                        analyseChapter.Article = analyseArticle.Article;
                        if (NovelStore.Instace().StoreChapters(analyseArticle.Rule.RuleID.Pattern, ref analyseBookReader, analyseChapter))
                        {
                            NovelStore.Instace().CompleteStore();
                        }
                    }
                    catch (Exception ex)
                    {
                        Utils.LogManage.Instace().Error(ex.Message);
                        //throw;
                    }
                    Thread.Sleep(ConfigManage.Instace().GetConfig().SleepBook);
                }
            }
        }

        private void GetNovel(string articleLink, ref AnalyseArticle analyseArticle)
        {
            analyseArticle.SetContent(Utils.HttpHelper.Get(articleLink, analyseArticle.Encode));
            if (string.IsNullOrEmpty(analyseArticle.GetContent()))
            {
                throw new Exception(string.Format("[103][NovelSpider] html is empty {0}",articleLink));
            }
            analyseArticle.AnalyseNovelInfo();

//#if DEBUG
            PrintNovel(analyseArticle.Rule.RuleID.Pattern, analyseArticle.Article);
//#endif
        }

        private void GetBookReaders(ref AnalyseArticle analyseArticle, ref AnalyseBookReader analyseBookReader)
        {
            analyseBookReader.Article = analyseArticle.Article;
            analyseBookReader.SetContent(Utils.HttpHelper.Get(analyseArticle.Article.contentslink, analyseArticle.Encode));
            if (!string.IsNullOrEmpty(analyseBookReader.GetContent()))
            {
                analyseBookReader.AnalyseVolumeList();
            }
            else
            {
                throw new Exception(string.Format("[104][NovelSpider] article contentslink is empty {0}", analyseArticle.Article.contentslink));
            }
//#if DEBUG
            PrintChapters(analyseArticle.Rule.RuleID.Pattern, analyseBookReader.BookReader);
//#endif
        }

        ///// <summary>
        ///// 存储所有备用规则与QIDIAN之间匹配的章节映射
        ///// </summary>
        //private readonly Dictionary<string, Dictionary<int, int>> _reserveRelations = new Dictionary<string, Dictionary<int, int>>();

        //private class DiffernceInfo
        //{
        //    public string Webflag { get; set; }
        //    public int Difference { get; set; }
        //}

        //private readonly IList<DiffernceInfo> _reserveDifferences = new List<DiffernceInfo>();

        //private void GetVipBookReader(AnalyseBookReader sourceBookReader)
        //{
        //    bool hasBestBefore;
        //    var reserveRules = SmartMatch.Instace().GetReserveRules(sourceBookReader.Article.articleid, out hasBestBefore);
        //    _reserveRelations.Clear();
        //    _reserveDifferences.Clear();
        //    var article = sourceBookReader.Article;
        //    foreach (var reserveRule in reserveRules)
        //    {
        //        var analyse = GetAnalyserAll(reserveRule);
        //        var analyseArticle = analyse.AnalyseArticler;
        //        var analyseBookReader = analyse.AnalyseBookReaderer;
        //        var analyseChapter = analyse.AnalyseChapter;

        //        SearchNovel(sourceBookReader.Article, reserveRule, ref analyseArticle);
        //        analyseArticle.Article.articleid = sourceBookReader.Article.articleid;
        //        analyseBookReader.Article = analyseArticle.Article;
        //        if (string.IsNullOrEmpty(analyseArticle.Article.contentslink))
        //        {
        //            Utils.LogManage.Instace().Error("[10007]article contentslink is empty");
        //            Utils.LogManage.Instace().Error(sourceBookReader.Article.articlename);
        //            return;
        //        }
        //        GetBookReaders(ref analyseArticle, ref analyseBookReader);
        //        if (ConfigManage.Instace().GetConfig().GatherType == "APP")
        //        {
        //            NovelStore.Instace().StoreChapters(reserveRule.RuleID.Pattern, ref analyseBookReader, analyseChapter);
        //        }

        //        int difference = 0;
        //        var relations = new Dictionary<int, int>();
        //        var hasBest = SmartMatch.Instace().MatchChapters(sourceBookReader.BookReader, analyseBookReader.BookReader, ref difference, ref relations);
        //        if (hasBest)
        //        {
        //            Utils.LogManage.Instace().Info(true, string.Format("[BEST]{0}{1}", article.articlename, article.contentslink));
        //            if (ConfigManage.Instace().GetConfig().GatherType == "WEB")
        //            {
        //                NovelStore.Instace().DownloadTxtReserve(sourceBookReader, analyseBookReader, analyseChapter, relations);
        //            }
        //            NovelStore.Instace().SaveBestMatch(article, reserveRule.RuleID.Pattern, hasBestBefore);
        //        }
        //        else
        //        {
        //            _reserveRelations[reserveRule.RuleID.Pattern] = relations; //将章节映射关系存入
        //            _reserveDifferences.Add(new DiffernceInfo {Webflag = reserveRule.RuleID.Pattern, Difference = difference});
        //        }
        //    }
        //    //所有备用站点未查询出best，则取用difference最少的规则
        //    if (_reserveDifferences.Count > 0 && ConfigManage.Instace().GetConfig().GatherType == "WEB")
        //    {
        //        var items = from s in _reserveDifferences
        //                    orderby s.Difference descending
        //                    select s;
        //        DiffernceInfo diff = items.First();
        //        NovelStore.Instace().DownloadTxtReserve(sourceBookReader,
        //                                                _dicAnalyser[diff.Webflag].AnalyseBookReaderer,
        //                                                _dicAnalyser[diff.Webflag].AnalyseChapter,
        //                                                _reserveRelations[diff.Webflag]);
        //    }
        //}

        //private AnalyserAll GetAnalyserAll(RuleEntity reserveRule)
        //{
        //    if (!_dicAnalyser.ContainsKey(reserveRule.RuleID.Pattern))
        //    {
        //        var analyse = new AnalyserAll
        //                          {
        //                              AnalyseArticler = new AnalyseArticle { Rule = reserveRule },
        //                              AnalyseBookReaderer = new AnalyseBookReader { Rule = reserveRule },
        //                              AnalyseChapter = new AnalyseChapter { Rule = reserveRule }
        //                          };
        //        _dicAnalyser[reserveRule.RuleID.Pattern] = analyse;
        //    }
        //    return _dicAnalyser[reserveRule.RuleID.Pattern];
        //}

//        /// <summary>
//        /// 通过查询方式采集小说信息页
//        /// </summary>
//        /// <param name="article"></param>
//        /// <param name="reserveRule"></param>
//        /// <param name="analyseArticle"></param>
//        private void SearchNovel(ArticleInfo article, RuleEntity reserveRule, ref AnalyseArticle analyseArticle)
//        {
//            //获取查找的URL
//            var searchLink = analyseArticle.AnalyseNovelSearchUrl(article.articlename);
//            analyseArticle.SetContent(Utils.HttpHelper.Get(searchLink, Encoding.GetEncoding(reserveRule.GetSiteCharset.Pattern)));
//            //从查询的HTML分析出article url
//            searchLink = analyseArticle.GetNovelLink(article.articlename);
//            if (string.IsNullOrEmpty(searchLink))
//            {
//                //从article url采集
//                analyseArticle.AnalyseNovelInfo();
//#if DEBUG
//                PrintNovel(analyseArticle.Rule.RuleID.Pattern, analyseArticle.Article);
//#endif
//            }
//            else
//            {
//                GetNovel(searchLink, ref analyseArticle);
//            }
//        }
    }
}
